/**
 *
 */
package com.naiterui.ehp.bs.doctor.controller;

import com.naiterui.ehp.bp.constants.SwaggerTag;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.support.exception.PublicService;
import com.naiterui.ehp.bp.support.exception.ResponseVO;
import com.naiterui.ehp.bp.utils.biz.NameUtils;
import com.naiterui.ehp.bp.utils.lang.StringUtil;
import com.naiterui.ehp.bs.doctor.exception.ExceptionCodes;
import com.naiterui.ehp.bs.doctor.service.IPatientGroupService;
import com.naiterui.ehp.bs.doctor.utils.LimitValueConfig;
import com.naiterui.ehp.bs.doctor.vo.PatientGroupVo;
import com.naiterui.ehp.bs.doctor.vo.PatientUserGroupVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

/**
 * @Description 医生分组控制层
 */
@Api(tags = {SwaggerTag.DOCTOR + SwaggerTag.PATIENT_MANAGER})
@RequestMapping("ad/patientGroup")
@Controller
public class AdPatientGroupController {

    private static final Logger LOGGER = LoggerFactory.getLogger(AdPatientGroupController.class);

    @Autowired
    private IPatientGroupService patientGroupService;

    /**
     * <获取分组列表>
     * @param doctorId
     * @return String <分组列表>
     * @Throws 异常信息
     * @History 2015-6-20 上午11:59:15 by guoyongxiang
     */
    @ApiOperation(value = "获取患者分组列表", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生ID", dataType = "long", paramType = "query", required = true),
    })
    @RequestMapping("list")
    @ResponseBody
    public ResponseVO<List<PatientGroupVo>> list(Long doctorId) {
        List<PatientGroupVo> vo = this.patientGroupService.findPatientGroupByDoctorId(doctorId);
        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS, vo);
    }

    /**
     * <患者分组新增>
     * <详细描述>
     * @param doctorId
     * @return String <返回值描述>
     * @Throws 异常信息
     * @History 2015年6月21日 下午4:55:57 by chenlin change by linhf 2016-07-01 V2.5.0 添加校验参数长度
     */
    @ApiOperation(value = "添加患者分组", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生ID", dataType = "long", paramType = "form", required = true),
            @ApiImplicitParam(name = "name", value = "分组名", dataType = "String", paramType = "form", required = true),
    })
    @RequestMapping("add")
    @ResponseBody
    public ResponseVO<Void> addGroup(Long doctorId, String name) throws BusinessException {

        LOGGER.info(" patientGroup add INFO : doctorId={}, name={}", doctorId, StringUtil.encodeUnicode(name));
        // 2.2.0 分组名称逻辑变更：不能为空
        name = this.handleName(name);
        if (StringUtils.isBlank(name)) {
            LOGGER.info(" patientGroup add ERROR ; illegal name : doctorId {}, name {}", doctorId, name);
            throw new BusinessException(ExceptionCodes.EMOJI_ERROR);
        }

        // V2.5.0 统一校验长度
        if (!LimitValueConfig.validateLimit(LimitValueConfig.LIMIT_PATIENTGROUPNAME, name)) {
            throw new BusinessException(ExceptionCodes.INVALID_CONTENT_LENGTH);
        }

        // 2.3 分组名称判断输入格式
        if (!name.matches(NameUtils.VALIDATE_REGEX_PT_GROUP_NAME)) {
            LOGGER.info(" patientGroup add ERROR ; illegal name : doctorId {}, name {}", doctorId, name);
            throw new BusinessException(ExceptionCodes.EMOJI_ERROR);
        }

        if (this.patientGroupService.findExsitGroupName(doctorId, name, null)) {
            throw new BusinessException(ExceptionCodes.PATIENT_GROUP_EXSIT);
        }

        this.patientGroupService.saveGroup(doctorId, name);
        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);
    }

    /**
     * 处理名称
     * PatientGroupController.handleName()
     * @Date 2016年4月28日
     * @since 2.3.0
     * @param name
     * @return
     */
    private String handleName(String name) {

        if (null != name) {
            name = name.trim().replaceAll("\\s+", " ").replaceAll(" +", " ");
        }
        return name;
    }

    /**
     * <患者分组修改>
     * <详细描述>
     * @param id
     * @param name
     * @return String <返回值描述>
     * @Throws 异常信息
     * @History 2015年6月21日 下午5:19:05 by chenlin
     */
    @ApiOperation(value = "修改患者分组名", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生ID", dataType = "long", paramType = "form", required = true),
            @ApiImplicitParam(name = "id", value = "分组ID", dataType = "long", paramType = "form", required = true),
            @ApiImplicitParam(name = "name", value = "分组名", dataType = "String", paramType = "form", required = true),
    })
    @RequestMapping("modify")
    @ResponseBody
    public ResponseVO<Void> modifyGroup(Long doctorId, Long id, String name) throws BusinessException {
        LOGGER.info("修改分组名：doctorId={}, id={}, name={}", doctorId, id, name);
        // 2.2.0 分组名称逻辑变更：不能为空
        name = this.handleName(name);
        if (StringUtils.isBlank(name)) {
            LOGGER.info(" patientGroup modify ERROR ; illegal name : doctorId {},name {}", doctorId, name);
            throw new BusinessException(ExceptionCodes.EMOJI_ERROR);
        }

        // V2.5.0 统一校验长度
        if (!LimitValueConfig.validateLimit(LimitValueConfig.LIMIT_PATIENTGROUPNAME, name)) {
            throw new BusinessException(ExceptionCodes.INVALID_CONTENT_LENGTH);
        }

        // 2.3 分组名称判断输入格式
        if (!name.matches(NameUtils.VALIDATE_REGEX_PT_GROUP_NAME)) {
            LOGGER.info(" patientGroup modify ERROR ; illegal name : doctorId {},name {}", doctorId, name);
            throw new BusinessException(ExceptionCodes.EMOJI_ERROR);
        }

        this.patientGroupService.updateGroup(doctorId, id, name);
        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);
    }

    /**
     * <患者分组删除>
     * <详细描述>
     * @return String <返回值描述>
     * @throws
     *         @Throws 异常信息
     * @History 2015年6月21日 下午5:19:05 by chenlin
     */
    @ApiOperation(value = "删除患者分组", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生ID", dataType = "long", paramType = "form", required = true),
            @ApiImplicitParam(name = "ids", value = "分组ID列表(英文逗号分隔)", dataType = "String", paramType = "form", required = true),
    })
    @RequestMapping("remove")
    @ResponseBody
    public ResponseVO<Void> removeGroup(Long doctorId, String ids) {
        if (ids != null) {
            String[] idArr = ids.split(",");
            for (String id : idArr) {
                this.patientGroupService.deleteGroup(Long.valueOf(id));
            }
        }
        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);
    }

    /**
     * 获取分组中的患者信息
     * <详细描述>
     * @return String <返回值描述>
     * @Throws 异常信息
     * @History 2015年6月21日 下午5:19:05 by chenlin
     */
    @ApiOperation(value = "获取分组中患者列表", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生ID", dataType = "long", paramType = "query", required = true),
            @ApiImplicitParam(name = "groupId", value = "分组ID", dataType = "long", paramType = "query", required = true),
    })
    @RequestMapping("listUser")
    @ResponseBody
    public ResponseVO<List<PatientUserGroupVo>> listUserGroup(Long doctorId, Long groupId) throws Exception {
        List<PatientUserGroupVo> vo = this.patientGroupService.findListUserGroup(groupId, doctorId);
        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS, vo);
    }

    /**
     * <向分组中添加患者>
     * <详细描述>
     * @return String <返回值描述>
     * @Throws 异常信息
     * @History 2015年6月21日 下午5:19:05 by chenlin
     */
    @ApiOperation(value = "向分组中添加患者", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生ID", dataType = "long", paramType = "form", required = true),
            @ApiImplicitParam(name = "groupId", value = "分组ID", dataType = "long", paramType = "form", required = true),
            @ApiImplicitParam(name = "patientIds", value = "患者ID列表(英文逗号分隔)", dataType = "String", paramType = "form", required = true),
    })
    @RequestMapping("addUser")
    @ResponseBody
    public ResponseVO<Void> addUser2Group(Long doctorId, Long groupId, String patientIds) throws BusinessException {
        this.patientGroupService.saveUser2Group(groupId, patientIds);
        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);
    }

    /**
     * <从分组中删除患者>
     * <详细描述>
     * @return String <返回值描述>
     * @Throws 异常信息
     * @History 2015年6月21日 下午5:19:05 by chenlin
     */
    @ApiOperation(value = "从分组中移除患者", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生ID", dataType = "long", paramType = "form", required = true),
            @ApiImplicitParam(name = "groupId", value = "分组ID", dataType = "long", paramType = "form", required = true),
            @ApiImplicitParam(name = "patientIds", value = "患者ID列表(英文逗号分隔)", dataType = "String", paramType = "form", required = true),
    })
    @RequestMapping("removeUser")
    @ResponseBody
    public ResponseVO<Void> removeUser2Group(Long doctorId, Long groupId, String patientIds) throws BusinessException {
        this.patientGroupService.deleteUser2Group(groupId, patientIds);
        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);
    }

    /**
     * 获取医生所有分组
     * @Description 获取医生所有分组，勾选出患者所在分组
     * @param doctorId
     * @param patientId
     * @return
     * @throws BusinessException
     * @History 2017年6月9日 by wangchuan
     */
    @ApiOperation(value = "获取医生所有分组", notes = "获取医生所有分组。注意：groupCount字段在本接口中忽略！", httpMethod = "POST")
    @ApiImplicitParams({ @ApiImplicitParam(name = "doctorId", value = "医生ID", required = true, dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "patientId", value = "患者ID", required = true, dataType = "long", paramType = "query") })
    @RequestMapping("/list/all")
    @ResponseBody
    public ResponseVO<List<PatientGroupVo>> getGroupList(Long doctorId, Long patientId) throws BusinessException {
        LOGGER.info("获取医生所有分组，doctorId={}, patientId={}", doctorId, patientId);
        if (doctorId == null) {
            LOGGER.info("获取医生所有分组，医生ID为空");
            throw new BusinessException(ExceptionCodes.PARAM_ERROR);
        }
        // 医生所有的分组，标记出患者所在的分组
        List<PatientGroupVo> groupList = this.patientGroupService.getGroupListByDoctor(doctorId, patientId);
        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS, groupList);
    }

    /**
     * 添加或者移除患者
     * @Description
     * @param doctorId 医生ID
     * @param patientId 患者ID
     * @param groupIds 分组id字符串，逗号分隔
     * @return
     * @throws BusinessException
     * @History 2017年6月9日 by wangchuan
     */
    @ApiOperation(value = "从分组中添加或者移除患者", notes = "从分组中添加或者移除患者", httpMethod = "POST")
    @ApiImplicitParams({ @ApiImplicitParam(name = "doctorId", value = "医生ID", required = true, dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "patientId", value = "患者ID", required = true, dataType = "long", paramType = "query"), @ApiImplicitParam(
            name = "groupIds", value = "患者所在分组ID串，逗号分隔。需要从全部分组中移除时，传空串''", required = true, dataType = "String", paramType = "query")
    })
    @RequestMapping("/modify/patient")
    @ResponseBody
    public ResponseVO<Void> modifyFromGroup(Long doctorId, Long patientId, String groupIds) throws BusinessException {
        LOGGER.info("从分组中添加或者移除患者，doctorId={}, patientId={}, groupIds={}", doctorId, patientId, groupIds);
        if (doctorId == null || patientId == null || groupIds == null) {
            LOGGER.info("从分组中添加或者移除患者，医生id、患者id或组id串为空");
            throw new BusinessException(ExceptionCodes.PARAM_ERROR);
        }

        // 添加或移除操作
        this.patientGroupService.updatePatientIncluded(doctorId, patientId, groupIds);

        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);
    }
}